﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TMRCPUEMULATOR
{
    /// <summary>
    /// Addressing mode for each opecode
    /// </summary>
    public enum ADDRESSMODE
    {
        NONE,
        Imeddiate1b,
        Imeddiate2b,
        Direct
    }

    /// <summary>
    /// OpCode Data represintation class
    /// </summary>
    public class OpCode
    {
        /// <summary>
        /// Name of this opcode
        /// </summary>
        public string Name
        {
            get;
            private set;
        }

        //Binary code of this opcode
        public byte Binary
        {
            get;
            private set;
        }

        //Addressing mode of this opcode
        public ADDRESSMODE AddressMode
        {
            get;
            private set;
        }

        /// <summary>
        /// OpCode Data represintation
        /// </summary>
        /// <param name="Name">Name of the opcode</param>
        /// <param name="Binary">Byte code of the opcode</param>
        /// <param name="Addressmode">Addessing mode of the opcode</param>
        public OpCode(string Name, byte Binary, ADDRESSMODE Addressmode)
        {
            this.Name = Name;
            this.Binary = Binary;
            this.AddressMode = Addressmode;

        }

        /// <summary>
        /// List of all opcodes avalable
        /// </summary>
        public static List<OpCode> LIST = new List<OpCode>()
        {
           new OpCode("NOP",0x00,ADDRESSMODE.NONE),
           new OpCode("HALT",0x01,ADDRESSMODE.NONE),
           new OpCode("RST",0x02,ADDRESSMODE.NONE),
           new OpCode("SUBR",0x03,ADDRESSMODE.Direct),
           new OpCode("RTN",0x04,ADDRESSMODE.NONE),
           new OpCode("BRK",0x05,ADDRESSMODE.NONE),
           new OpCode("DSI",0x06,ADDRESSMODE.NONE),
           new OpCode("ENI",0x07,ADDRESSMODE.NONE),

           new OpCode("LDA",0x08,ADDRESSMODE.Imeddiate1b),
           new OpCode("LDAM",0x09,ADDRESSMODE.Direct),
           new OpCode("LDPC",0x0A,ADDRESSMODE.Imeddiate2b),
           new OpCode("LDSP",0x0B,ADDRESSMODE.Imeddiate2b),

           new OpCode("STA",0x0C,ADDRESSMODE.Direct),
           new OpCode("STPC",0x0D,ADDRESSMODE.Direct),
           new OpCode("STSP",0x0E,ADDRESSMODE.Direct),
           
           new OpCode("PSH",0x0F,ADDRESSMODE.Imeddiate1b),
           new OpCode("PSHM",0x10,ADDRESSMODE.Direct),
           new OpCode("PSHA",0x11,ADDRESSMODE.NONE),
           new OpCode("PSHPC",0x12,ADDRESSMODE.NONE),
           new OpCode("PSHSP",0x13,ADDRESSMODE.NONE),
           
           new OpCode("POPA",0x14,ADDRESSMODE.NONE),
           new OpCode("POPPC",0x15,ADDRESSMODE.NONE),
           new OpCode("POPSP",0x16,ADDRESSMODE.NONE),
           new OpCode("POP",0x17,ADDRESSMODE.Direct),

           new OpCode("ADD",0x18,ADDRESSMODE.Imeddiate1b),
           new OpCode("ADDC",0x19,ADDRESSMODE.Imeddiate1b),
           new OpCode("SUB",0x26,ADDRESSMODE.Imeddiate1b),
           new OpCode("SUBC",0x27,ADDRESSMODE.Imeddiate1b),
           new OpCode("DIV",0x28,ADDRESSMODE.Imeddiate1b),
           new OpCode("XOR",0x29,ADDRESSMODE.Imeddiate1b),
           new OpCode("XORM",0x05,ADDRESSMODE.Direct),
           new OpCode("NEG",0x06,ADDRESSMODE.NONE),
           new OpCode("AND",0x07,ADDRESSMODE.Imeddiate1b),
           new OpCode("ANDM",0x08,ADDRESSMODE.Direct),
           new OpCode("OR",0x07,ADDRESSMODE.Imeddiate1b),
           new OpCode("ORM",0x08,ADDRESSMODE.Direct),



        };

    }
}


